以下代码均来自hopeful,渣渣我只是解读一下
一.大体
首先在自定义插件VirtualJoystick(后称VJ)中我们需要实现的通过UI进行交互的功能有:
1.跟随手指在屏幕上进行移动
2.在松手时回到中心
3.实现和MemoryTable以及VelocityTable之间数据的交互(主要实现方法还是在MemoryTable以及VelocityTable中)
4.根据传达回来的重力感应数据进行变化
我们先大体看一下这个类中有几个变量和几个方法:
变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| private Thread thread;
private SurfaceHolder holder;
private Paint paint;
private onJoystickMoveListener listener;
private boolean touchDownFlag;
private boolean istouch;
private int outer_radius;
private int inner_radius;
private PointF position;
|
方法:


二.public VirtualJoystick()
三个构造函数其中主要的内容就是初始化surface的内容,即
init()
给VJ实体化中的变量实体化
三.get函数和set函数
获取当前摇杆坐标的X坐标 Y坐标
获取是否由触屏事件
设置是否由触屏事件
很简单,不细讲
四.private void init()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| private void init(){ paint = new Paint(); paint.setAntiAlias(true); position = new PointF(0, 0); holder = this.getHolder(); holder.addCallback(new SurfaceHolder.Callback() { public void surfaceCreated(SurfaceHolder holder) { thread = new Thread(new Runnable() {
public void run() { while (true) { try { mDraw(); Thread.sleep(50); } catch (InterruptedException e) {
} } } }); thread.start(); }
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) { thread.interrupt(); thread = null; } });
}
|
五、@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
1 2 3 4 5 6 7 8 9 10 11
| protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { outer_radius = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)) / 2; inner_radius = outer_radius / 2; setMeasuredDimension(outer_radius * 2, outer_radius * 2); }
|
六、private void mDraw()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| private void mDraw() { Canvas c = null; try { c = holder.lockCanvas(); if (c == null) return; c.drawColor(Color.WHITE);
paint.setColor(getResources().getColor(R.color.vj_bg)); c.drawCircle(outer_radius, outer_radius, outer_radius, paint);
paint.setColor(getResources().getColor(R.color.vj_control)); c.drawCircle(outer_radius + position.x, outer_radius + position.y, inner_radius, paint); c.drawCircle(outer_radius, outer_radius, inner_radius / 2, paint); } catch (Exception e) {
} finally { if (c != null) holder.unlockCanvasAndPost(c); } }
|
七、public boolean onTouchEvent(MotionEvent event)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public boolean onTouchEvent(MotionEvent event) { float tx = event.getX(), ty = event.getY(); istouch = true; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touchDownFlag = true;
case MotionEvent.ACTION_MOVE: if (!touchDownFlag) break;
tx -= outer_radius; ty -= outer_radius;
if (Math.pow(tx, 2) + Math.pow(ty, 2) > Math.pow(outer_radius - inner_radius, 2)) { double angle = Math.atan(ty / tx); position.set(Math.signum(tx) * (outer_radius - inner_radius) * (float) Math.cos(angle), Math.signum(tx) * (outer_radius - inner_radius) * (float) Math.sin(angle)); } else position.set(tx, ty); break;
case MotionEvent.ACTION_UP: touchDownFlag = false; position.set(0, 0); break; } if (listener != null) listener.onMove(position.x / (outer_radius - inner_radius), position.y / (outer_radius - inner_radius)); return true; }
|
八、public void setOnJoystickMoveListener && public interface onJoystickMoveListener
1 2 3 4 5 6 7 8 9 10
| public void setOnJoystickMoveListener(onJoystickMoveListener listener) { this.listener = listener; }
public interface onJoystickMoveListener { void onMove(float dx, float dy); }
|
九、public void JoystickChangeByGravity(int which)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public void JoystickChangeByGravity(int which) { if (which == 1) position.set(outer_radius / 2, 0); else if (which == 2) position.set(0, outer_radius / 2); else if (which == 3) position.set(outer_radius / 2 * -1, 0); else if (which == 4) position.set(0, outer_radius / 2 * -1);
if (listener != null) listener.onMove(position.x / (outer_radius - inner_radius), position.y / (outer_radius - inner_radius)); }
public void resetJoystick() { position.set(0, 0);
if (listener != null) listener.onMove(position.x / (outer_radius - inner_radius), position.y / (outer_radius - inner_radius)); }
|